package org.shushan.cloud.transaction.sample.controller;


import io.seata.spring.annotation.GlobalTransactional;
import org.apache.curator.framework.CuratorFramework;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.shushan.cloud.transaction.sample.entity.UserEntity;
import org.shushan.cloud.transaction.sample.service.UserService;
import org.shushan.cloud.transaction.sample.service.UserTccService;
import org.shushan.cloud.transaction.sample.vo.UserPageRequest;
import org.shushan.cloud.transaction.sample.vo.UserRequest;
import org.shushan.cloud.transaction.sample.vo.UserResponse;
import org.shushan.framework.core.resp.Result;
import org.shushan.framework.transaction.service.TransactionLocalService;
import org.shushan.framework.web.base.CrudController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * @author zhigang.li
 * @date 2022/6/19
 
 
 */
@RestController
@RequestMapping("user")
public class UserController extends CrudController<UserPageRequest, UserRequest, UserResponse, String, UserEntity, UserService> {

    @GetMapping("test")
    @ResponseBody
    public String test(String name, String id) {
        return service.test(name, id);
    }


    @Autowired
    CuratorFramework client;

    @ResponseBody
    @PostMapping({"transaction"})
    public Result<UserResponse> transaction(@Validated @RequestBody UserRequest request) {
        this.service.saveTransaction(request);
        return Result.ok();
    }

    @GetMapping("lock")
    @ResponseBody
    public String lock() throws InterruptedException {

        for (int i = 0; i < 10; i++) {
            service.lock(i);
        }
        return "lock";
    }

    @Autowired
    RocketMQTemplate rocketMQTemplate;

    //测试消息的发送,事务消息发送
    @GetMapping("rocketmq")
    @ResponseBody
    public Result<UserResponse> rocketmq() {
        UserEntity userEntity = new UserEntity();
        userEntity.setId("11111111");
        Message<UserEntity> message = MessageBuilder.withPayload(userEntity).build();
        //传入一个TransactionLocalService来执行本地业务逻辑
        TransactionSendResult testmq = rocketMQTemplate.sendMessageInTransaction("testmq", message, new TransactionLocalService() {
            @Override
            public void executeLocalTransaction() {
                //执行本地业务逻辑
                service.save(userEntity);
                //让它失败
            }
        });
        LocalTransactionState localTransactionState = testmq.getLocalTransactionState();
        System.out.println(localTransactionState);
        return Result.ok();
    }


    @Autowired
    UserTccService tccTransactionService;

    @GetMapping("tccTest")
    @ResponseBody
    @GlobalTransactional
    public Result<UserResponse> tccTest() {
        UserEntity userEntity = new UserEntity();
        userEntity.setId("11111111");
        tccTransactionService.prepare(null, userEntity);
        return Result.ok();
    }

}
